﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Core;
using MugenMvvmToolkit.Interfaces;
using MugenMvvmToolkit.Utils;

namespace MugenMvvmToolkit.Infrastructure
{
    /// <summary>
    /// Represents the implemenation of <see cref="IThreadManager"/> that can be used for unit-test, all action invokes in the same thread.
    /// </summary>
    public class SynchronousThreadManager : IThreadManager
    {
        #region Implementation of IThreadManager

        /// <summary>
        ///     Gets or sets a dispatcher associated with current UI thread.
        /// </summary>
        public CoreDispatcher UiDispatcher { get; set; }

        /// <summary>
        /// Gets or sets the priority of asynchronous operations.
        /// </summary>
        public CoreDispatcherPriority AsynchronousPriority { get; set; }

        /// <summary>
        /// Gets or sets the priority of synchronous operations.
        /// </summary>
        public CoreDispatcherPriority SynchronousPriority { get; set; }

        /// <summary>
        ///     Invokes an action on the UI thread using the UiDispatcher.
        /// </summary>
        /// <param name="action">
        ///     The specified <see cref="Action" />.
        /// </param>
        /// <param name="priority">The specified <see cref="CoreDispatcherPriority"/> to invoke the action.</param>
        public void InvokeInUi(Action action, CoreDispatcherPriority priority)
        {
            InvokeInUiSynchronous(action);
        }

        /// <summary>
        ///     Invokes an action on the UI thread synchronous using the UiDispatcher.
        /// </summary>
        /// <param name="action">
        ///     The specified <see cref="Action" />.
        /// </param>
        /// <param name="priority">The specified <see cref="CoreDispatcherPriority"/> to invoke the action.</param>
        public void InvokeInUiSynchronous(Action action, CoreDispatcherPriority priority)
        {
            InvokeInUiSynchronous(action);
        }

        /// <summary>
        /// Determines whether the calling thread is the UI thread.
        /// </summary>        
        /// <returns><c>true</c> if the calling thread is the UI thread; otherwise, <c>false</c>.</returns>
        public bool IsUiThread { get; set; }

        /// <summary>
        ///     Invokes an action on the UI thread using the UiDispatcher.
        /// </summary>
        /// <param name="action">
        ///     The specified <see cref="Action" />.
        /// </param>
        public void InvokeInUi(Action action)
        {
            InvokeInUiSynchronous(action);
        }

        /// <summary>
        ///     Invokes an action on the UI thread synchronous using the UiDispatcher.
        /// </summary>
        /// <param name="action">
        ///     The specified <see cref="Action" />.
        /// </param>
        public void InvokeInUiSynchronous(Action action)
        {
            Should.NotBeNull(action, "action");
            action();
        }

        /// <summary>
        ///     Invokes an action asynchronous.
        /// </summary>
        /// <param name="action">
        ///     The specified <see cref="Action" />.
        /// </param>
        /// <param name="state">The specified state.</param>
        public void InvokeAsync(Action<object> action, object state = null)
        {
            Should.NotBeNull(action, "action");
            action(state);
        }

        /// <summary>
        /// Gets or sets a <see cref="TaskScheduler"/> associated with current UI thread.
        /// </summary>
        public TaskScheduler UiTaskScheduler { get; set; }

        /// <summary>
        /// Gets or sets a <see cref="TaskScheduler"/> not associated with current UI thread.
        /// </summary>
        public TaskScheduler NonUiTaskScheduler { get; set; }

        #endregion
    }
}
